/**
 * 试剂列表
 */
import { FC, useEffect, useState, useMemo, useRef } from "react";
import { observer, inject } from "mobx-react";
import {
  Row,
  Col,
  Button,
  Modal,
  Form,
  Input,
  message,
  Space,
  Alert,
  AutoComplete,
  Typography,
  Upload,
  Dropdown,
  Switch,
  Select,
  notification,
  Spin,
  InputNumber,
  Tooltip,
  Progress,
} from "antd";
import type { UploadProps, MenuProps } from "antd";
import {
  PlusOutlined,
  DownloadOutlined,
  UploadOutlined,
  ScanOutlined,
  InfoCircleOutlined,
  ImportOutlined,
  CloudDownloadOutlined,
} from "@ant-design/icons";
import * as XLSX from "xlsx";
import { RcFile } from "rc-upload/lib/interface";
import _ from "lodash";
import { createWorker } from "tesseract.js";
import ReagentList from "./ReagentList";
import { ITStore } from "../../store";
import { ITDictValue, ITReagent } from "../../store/interfaces";
import {
  expReagentJson,
  expReagentExcel,
  MockReagentData,
  MockCasReagentData,
  formatJsonFile,
  formatXlsxFile,
} from "../../utils/exportReagents";

const { Option } = Select;
const { Link } = Typography;

const layout = {
  labelCol: { span: 8 },
  wrapperCol: { span: 16 },
};

type TProp = {
  store: ITStore;
  searchForm?: any;
};

type TSearchOpt = {
  label: string;
  value: string;
  id?: string;
};

type TCasForm = {
  casno: string;
};

interface ITScanModalProp extends TProp {
  showScanCasModal: boolean;
  close: () => void;
}

interface ITSearchAddCompProp extends TProp {
  setShowScanCasModal: (data: boolean) => void;
  changeShowCasModal: (data: boolean) => void;
  searchForm: any;
}

interface ITCasImportModalProp extends TProp {
  isShow: boolean;
  changeShow: (data: boolean) => void;
}

function chunk(arr: any, size: number) {
  let newArr = [];
  for (let i = 0; i < arr.length; i = i + size) {
    newArr.push(arr.slice(i, i + size));
  }
  return newArr;
}

const splitUplist = (list: string[]) => {
  let splitNum = 1;
  let splitCount = 1;
  const listLength = list.length;
  if (listLength > 20 && listLength <= 100) {
    splitCount = 5;
  } else if (listLength > 100 && listLength < 200) {
    splitCount = 10;
  } else if (listLength >= 200 && listLength < 500) {
    splitCount = 20;
  } else if (listLength >= 500 && listLength < 1000) {
    splitCount = 50;
  } else if (listLength >= 1000) {
    splitCount = 100;
  }
  splitNum = Math.ceil(listLength / splitCount);

  return {
    num: splitCount,
    list: chunk(list, splitNum),
  };
};

// 检查文件是txt json 或 xlsx csv
const checkFileType = (fileName: string): string => {
  const lowFileName = fileName.toLocaleLowerCase();
  const txtjson = [".txt", ".json"];
  const slsxcsv = [".xlsx", ".csv"];

  let type = "";
  txtjson.some((item) => {
    if (lowFileName.indexOf(item) >= 0) {
      type = "txtjson";
      return true;
    }
    return false;
  });

  if (!type) {
    slsxcsv.some((item) => {
      if (lowFileName.indexOf(item) >= 0) {
        type = "xlsxcsv";
        return true;
      }
      return false;
    });
  }
  return type;
};

// 检查根据Casno导入的文件是否存在重复
const checkRepeat = (data: any): { repeatList: string[]; list: any } => {
  let Obj: {
    [casno: string]: any;
  } = {};
  let repeatList: string[] = [];
  data.forEach((element: any) => {
    const { casno } = element;
    if (!Obj[casno]) {
      Obj[casno] = element;
    } else {
      repeatList.push(casno);
    }
  });
  return {
    repeatList,
    list: Object.values(Obj),
  };
};

// Cas号批量导入
const CasImportModal: FC<ITCasImportModalProp | any> = inject("store")(
  observer(({ store, isShow, changeShow }: ITCasImportModalProp) => {
    const {
      languageStore: { lang },
      reagentStore: { getReagentList, ImportAllCasData, getAllReagetList },
    } = store;

    const [form] = Form.useForm();

    const [fileList, setFileList] = useState<RcFile[]>([]);

    const [upData, setupData] = useState<ITReagent[] | null>(null);

    const [importLoading, setImportLoading] = useState(false);

    const [perc, setPerc] = useState<number>(0);

    const upprops = {
      maxCount: 1,
      accept: ".xlsx,.csv,.json,.txt",
      onRemove: () => {
        setFileList([]);
        setupData(null);
      },
      beforeUpload: (file: RcFile) => {
        const { name } = file;
        const fileType = checkFileType(name);
        const reader = new FileReader();

        if (fileType === "txtjson") {
          reader.readAsText(file, "UTF-8");
          reader.onload = (data: any) => {
            const fileString = data.target.result;
            try {
              const fileJson = JSON.parse(fileString);
              const upJsonFile: ITReagent[] = formatJsonFile(fileJson);
              setupData(upJsonFile);
            } catch (e) {}
          };
        } else {
          reader.readAsArrayBuffer(file);
          reader.onload = (event: any) => {
            const { result } = event.target;
            const workbook = XLSX.read(result, { type: "buffer" });
            let data: any = {};
            for (const sheet in workbook.Sheets) {
              let tempData: any[] = [];
              if (workbook.Sheets.hasOwnProperty(sheet)) {
                data[sheet] = tempData.concat(
                  XLSX.utils.sheet_to_json(workbook.Sheets[sheet])
                );
              }
            }
            const excelData = data.Sheet1;
            const upJsonFile = formatXlsxFile(excelData);

            const { repeatList, list } = checkRepeat(upJsonFile);

            if (repeatList.length) {
              let defaultStr = lang["langimpregtip"] || "";
              let tempStr = defaultStr
                .replace("{1}", upJsonFile.length + "")
                .replace("{2}", repeatList.length + "")
                .replace("{3}", list.length);
              message.warning(tempStr, 10);
            }

            setupData(upJsonFile);
          };
        }
        setFileList([file]);
        return false;
      },
      fileList,
    };

    const closemodal = () => {
      setFileList([]);
      form.resetFields();
      changeShow(false);
    };

    const onFinish = async () => {
      if (upData && upData.length) {
        // 获取所有化学试剂，看是否有重复，这里根据名称判断是否有重复
        setImportLoading(true);
        const allreagents = await getAllReagetList();
        let lastList: string[] = [];
        if (allreagents && allreagents.length) {
          let duplist: string[] = [];
          upData.forEach((item) => {
            let hasReagent = allreagents.some((sitem) => {
              if (item.casno && item.casno === sitem.casno) {
                duplist.push(sitem.casno);
                return true;
              }
              return false;
            });
            if (!hasReagent && item.casno) {
              lastList.push(item.casno);
            }
          });
          if (duplist.length) {
            notification.warn({
              message: `${duplist.join(",")} ${lang["langduplicate"]}!`,
              duration: null,
            });
            setImportLoading(false);
          }
        } else {
          upData.forEach((item) => {
            lastList.push(item.casno);
          });
        }
        const { num, list } = splitUplist(lastList);

        const addFinished = () => {
          message.success(lang["langimportsuccess"]);
          getReagentList();
          closemodal();
        };

        const addList = async (index: number) => {
          await ImportAllCasData(list[index]);
          index++;
          setPerc(((index + 1) / num) * 100);
          if (index < num) {
            addList(index);
          } else {
            addFinished();
          }
        };
        addList(0);
      }
    };

    return (
      <Modal
        title={lang["langimportreagent"]}
        open={isShow}
        onOk={() => {
          form.submit();
        }}
        onCancel={closemodal}
        destroyOnClose={true}
        confirmLoading={importLoading}
      >
        <Form
          name="upForm"
          form={form}
          labelCol={{ span: 6 }}
          wrapperCol={{ span: 16 }}
          onFinish={onFinish}
        >
          <Form.Item
            label=""
            name="file"
            rules={[{ required: true, message: lang["langupfiletip"] }]}
          >
            <Upload {...upprops}>
              <Button icon={<UploadOutlined />}>
                {lang["langselectfile"]}
              </Button>
            </Upload>
          </Form.Item>
        </Form>
        <Alert
          message={lang["langimportcasautotip"]}
          type="info"
          style={{ margin: "10px 0" }}
        />
        <Alert
          message={lang["reagentuptip"]}
          type="info"
          style={{ margin: "10px 0" }}
        />
        {lang["langtemplatefile"]}
        <Space>
          <Link
            onClick={() => {
              expReagentExcel(MockCasReagentData, "reagentlist.xlsx");
            }}
          >
            .xlsx
          </Link>
          <Link
            onClick={() => {
              expReagentExcel(MockCasReagentData, "reagentlist.csv");
            }}
          >
            .csv
          </Link>
          <Link
            onClick={() => {
              expReagentJson(MockCasReagentData, "reagentlist.json");
            }}
          >
            .json
          </Link>
          <Link
            onClick={() => {
              expReagentJson(MockCasReagentData, "reagentlist.txt");
            }}
          >
            .txt
          </Link>
        </Space>
        {perc > 0 && <Progress percent={perc} status="active" />}
      </Modal>
    );
  })
);

// 导入数据弹窗
const ImportModal: FC<TProp | any> = inject("store")(
  observer(({ store }: TProp) => {
    const {
      languageStore: { lang },
      reagentStore: {
        showImportModal,
        changeShowImportModal,
        getReagentList,
        ImportData,
        getAllReagetList,
      },
    } = store;

    const [form] = Form.useForm();

    const [fileList, setFileList] = useState<RcFile[]>([]);

    const [upData, setupData] = useState<ITReagent[] | null>(null);

    const [importLoading, setImportLoading] = useState(false);

    const upprops = {
      maxCount: 1,
      accept: ".xlsx,.csv,.json,.txt",
      onRemove: () => {
        setFileList([]);
        setupData(null);
      },
      beforeUpload: (file: RcFile) => {
        const { name } = file;
        const fileType = checkFileType(name);
        const reader = new FileReader();

        if (fileType === "txtjson") {
          reader.readAsText(file, "UTF-8");
          reader.onload = (data: any) => {
            const fileString = data.target.result;
            try {
              const fileJson = JSON.parse(fileString);
              const upJsonFile: ITReagent[] = formatJsonFile(fileJson);
              setupData(upJsonFile);
            } catch (e) {}
          };
        } else {
          reader.readAsArrayBuffer(file);
          reader.onload = (event: any) => {
            const { result } = event.target;
            const workbook = XLSX.read(result, { type: "buffer" });
            let data: any = {};
            for (const sheet in workbook.Sheets) {
              let tempData: any[] = [];
              if (workbook.Sheets.hasOwnProperty(sheet)) {
                data[sheet] = tempData.concat(
                  XLSX.utils.sheet_to_json(workbook.Sheets[sheet])
                );
              }
            }
            const excelData = data.Sheet1;
            const upJsonFile = formatXlsxFile(excelData);
            setupData(upJsonFile);
          };
        }
        setFileList([file]);
        return false;
      },
      fileList,
    };

    const closemodal = () => {
      setFileList([]);
      form.resetFields();
      changeShowImportModal(false);
    };

    const onFinish = async () => {
      if (upData && upData.length) {
        // 获取所有化学试剂，看是否有重复，这里根据名称判断是否有重复
        setImportLoading(true);
        const allreagents = await getAllReagetList();
        if (allreagents && allreagents.length) {
          let duplist: string[] = [];
          upData.forEach((item) => {
            return allreagents.some((sitem) => {
              if (item.name === sitem.name) {
                duplist.push(item.name);
                return true;
              }
              return false;
            });
          });
          if (duplist.length) {
            notification.error({
              message: `${duplist.join(",")} ${lang["langduplicate"]}!`,
              duration: null,
            });
            setImportLoading(false);
            return false;
          }
        }
        const result = await ImportData(upData);
        setImportLoading(false);
        if (!result) {
          message.success(lang["langimportsuccess"]);
          getReagentList();
          closemodal();
        }
      }
    };

    return (
      <Modal
        title={lang["langimportreagent"]}
        open={showImportModal}
        onOk={() => {
          form.submit();
        }}
        onCancel={closemodal}
        destroyOnClose={true}
        confirmLoading={importLoading}
      >
        <Form
          name="upForm"
          form={form}
          labelCol={{ span: 6 }}
          wrapperCol={{ span: 16 }}
          onFinish={onFinish}
        >
          <Form.Item
            label=""
            name="file"
            rules={[{ required: true, message: lang["langupfiletip"] }]}
          >
            <Upload {...upprops}>
              <Button icon={<UploadOutlined />}>
                {lang["langselectfile"]}
              </Button>
            </Upload>
          </Form.Item>
        </Form>
        <Alert
          message={lang["reagentuptip"]}
          type="info"
          style={{ margin: "10px 0" }}
        />
        {lang["langtemplatefile"]}
        <Space>
          <Link
            onClick={() => {
              expReagentExcel(MockReagentData, "reagentlist.xlsx");
            }}
          >
            .xlsx
          </Link>
          <Link
            onClick={() => {
              expReagentExcel(MockReagentData, "reagentlist.csv");
            }}
          >
            .csv
          </Link>
          <Link
            onClick={() => {
              expReagentJson(MockReagentData, "reagentlist.json");
            }}
          >
            .json
          </Link>
          <Link
            onClick={() => {
              expReagentJson(MockReagentData, "reagentlist.txt");
            }}
          >
            .txt
          </Link>
        </Space>
      </Modal>
    );
  })
);

// 导出数据弹窗
const ExportModal: FC<TProp | any> = inject("store")(
  observer(({ store }: TProp) => {
    const {
      languageStore: { lang },
      reagentStore: {
        showExportModal,
        changeShowExportModal,
        getAllReagetList,
      },
    } = store;

    const closemodal = () => {
      changeShowExportModal(false);
    };

    const getalldata = async () => {
      const reagents = await getAllReagetList();
      return reagents;
    };

    // 导出为json
    const exportReagentJson = async () => {
      const data = await getalldata();
      expReagentJson(data, "reagentlist.json");
    };

    // 导出为excel
    const exportReagentExcel = async () => {
      const data = await getalldata();
      expReagentExcel(data, "reagentlist.xlsx");
    };

    // 导出为csv
    const exportReagenCsv = async () => {
      const data = await getalldata();
      expReagentExcel(data, "reagentlist.csv");
    };

    return (
      <Modal
        title={lang["langexportreagentlist"]}
        open={showExportModal}
        onOk={() => {}}
        onCancel={closemodal}
        confirmLoading={false}
        footer={null}
      >
        <Row>
          <Col span={4}></Col>
          <Col span={16}>
            <Space>
              <Button type="primary" onClick={exportReagentJson}>
                {lang["langexport"]} json
              </Button>
              <Button type="primary" onClick={exportReagentExcel}>
                {lang["langexport"]} excel
              </Button>
              <Button type="primary" onClick={exportReagenCsv}>
                {lang["langexport"]} csv
              </Button>
            </Space>
          </Col>
          <Col span={4}></Col>
        </Row>
      </Modal>
    );
  })
);

// 搜索
const Search: FC<TProp | any> = inject("store")(
  observer(({ store, searchForm }: TProp) => {
    const {
      languageStore: { lang },
      reagentStore: { searchUserReagent, searchLoading, changeSearchList , getUserReagentList},
      userStore: { getUserInfo },
    } = store;

    const [allOptions, setAllOptions] = useState<TSearchOpt[]>([]);

    const [tempSearchList, setTempSearchList] = useState<ITReagent[]>([]);

    const onFinish = (values: any) => {
      const { keyward } = values;
      const userInfo = getUserInfo();
      if(!keyward){
        getUserReagentList({
          user: userInfo?.id,
        })
      } else {

      }
      changeSearchList(tempSearchList);
    };

    const onSelect = (value: string, data: TSearchOpt) => {
      let selectItem: ITReagent | null = null;
      tempSearchList.some((item) => {
        if (item.id === data.id) {
          selectItem = item;
          return true;
        }
        return false;
      });
      if (selectItem) {
        changeSearchList([selectItem]);
      }
    };

    const onSearch = async (data: any) => {
        const userInfo = getUserInfo();
      if (data && data.length >= 2) {
        const res: ITReagent[] = await searchUserReagent({ keyword: data, user: userInfo?.id });
        setTempSearchList(res);
        let tempOpt: TSearchOpt[] = [];
        if (res && res.length && data) {
          res.forEach((item) => {
            const { name, cnname, casno, formula, id } = item;
            const label = `${name} ${cnname ? cnname : ""} ${
              formula ? formula : ""
            } ${casno ? casno : ""}`;
            tempOpt.push({
              label,
              value: label.trim(),
              id,
            });
          });
        }
        setAllOptions(tempOpt);
      } else {
        setAllOptions([]);
      }
    };

    const debounceSearch = _.debounce(onSearch, 800);

    const reset = () => {
      searchForm.resetFields();
      setAllOptions([]);
      changeSearchList(null);
    };

    return (
      <Form name="search" layout="inline" form={searchForm} onFinish={onFinish}>
        <Form.Item name="keyward" label={""}>
          <AutoComplete
            style={{
              width: 460,
            }}
            options={allOptions}
            onSelect={onSelect}
            onSearch={debounceSearch}
            dropdownMatchSelectWidth={320}
            allowClear={true}
            onClear={reset}
            placeholder={lang["langselreagentplaceholder"]}
            notFoundContent={searchLoading ? <Spin size="small" /> : null}
          />
        </Form.Item>
        <Form.Item>
          <Button
            type="primary"
            onClick={() => {
              searchForm.submit();
            }}
          >
            {lang["langbuttonsearch"]}
          </Button>
        </Form.Item>
        <Form.Item>
          <Button type="default" onClick={reset}>
            {lang["langbuttonreset"]}
          </Button>
        </Form.Item>
      </Form>
    );
  })
);

// 搜索和新增按钮组件
const SearchAddComp: FC<ITSearchAddCompProp | any> = inject("store")(
  observer(
    ({
      store,
      setShowScanCasModal,
      changeShowCasModal,
      searchForm,
    }: ITSearchAddCompProp) => {
      const {
        languageStore: { lang },
        reagentStore: {
          changeShowAddEditModal,
          changeShowExportModal,
          changeShowImportModal,
        },
      } = store;

      // const [form] = Form.useForm();

      const handleClickAdd = () => {
        changeShowAddEditModal(true);
      };

      // 导入数据按钮
      const clickImport = () => {
        changeShowImportModal(true);
      };

      // 导出数据
      const clickExport = () => {
        changeShowExportModal(true);
      };

      // Cas批量导入
      const clickCasImport = () => {
        changeShowCasModal(true);
      };

      const menuClick = (data: any) => {
        const { key } = data;
        if (key === "1") {
          clickExport();
        } else if (key === "2") {
          clickImport();
        } else if (key === "3") {
          clickCasImport();
        }
      };

      const items: MenuProps["items"] = [
        {
          label: lang["langdataexport"],
          key: "1",
          icon: <DownloadOutlined />,
        },
        {
          label: lang["langimportdata"],
          key: "2",
          icon: <UploadOutlined />,
        },
        {
          label: lang["langbulkimportcasno"],
          key: "3",
          icon: <ImportOutlined />,
        },
      ];

      const menu = {
        items,
        onClick: menuClick,
      };

      return (
        <Row style={{ marginBottom: 20 }}>
          <Col span={12}>
            <Search searchForm={searchForm} />
          </Col>
          <Col span={12}>
            <Space wrap style={{ float: "right" }}>
              <Button
                type="primary"
                icon={<PlusOutlined />}
                onClick={handleClickAdd}
              >
                {lang["langbuttonadd"]}
              </Button>

              {/* <Button
                type="primary"
                icon={<ScanOutlined />}
                onClick={() => {
                  setShowScanCasModal(true);
                }}
              >
                {lang["scancas"]}
              </Button>

              <Dropdown.Button menu={menu}>
                {lang["langdatamanage"]}
              </Dropdown.Button> */}
            </Space>
          </Col>
        </Row>
      );
    }
  )
);

const nistSearchUrl = "https://webbook.nist.gov/chemistry/cas-ser/";
const nistSearchCas = "https://webbook.nist.gov/cgi/cbook.cgi?ID=";

// const chemsrc = "https://www.chemsrc.com/en/searchResult/";
// const chemsrcHome = "https://www.chemsrc.com/en/";

// const mercksrc = `https://www.sigmaaldrich.cn/CN/zh/search/7664-93-9?focus=products&page=1&perpage=30&sort=relevance&term=7664-93-9&type=cas_number`
const mercksrc = (casno: string) => {
  return `https://www.sigmaaldrich.cn/CN/zh/search/${casno}?focus=products&page=1&perpage=30&sort=relevance&term=${casno}&type=cas_number`;
};
const merckHome = "https://www.sigmaaldrich.cn/CN/zh";

// const xmolsrc = "https://www.x-mol.com/property?keyWord=";
// const xmolHome = "https://www.x-mol.com/chemicals";

// 新增编辑试剂弹窗
export const ReagentModal: FC<TProp | any> = inject("store")(
  observer(({ store }: TProp) => {
    const {
      languageStore: { lang, langCur },
      dictionaryStore: { getDictValuesByKey },
      reagentStore: {
        showAddEditModal,
        changeShowAddEditModal,
        addUserReagent,
        editUserReagent,
        addEditReagentLoading,
        getUserReagentList,
        getAllReagetList,
        editingReagentData,
        changeEditingReagentData,
        getReagentInfoByCasno,
        searchList,
        changeSearchList,
      },
      userStore: { getUserInfo },
    } = store;

    const [form] = Form.useForm();

    const [imgUrl, setImgUrl] = useState<string>("");

    const [getStructLoading, setGetStructLoading] = useState(false);

    const [nistUrl, setNistUrl] = useState<string>(nistSearchUrl);

    const [chemUrl, setChemUrl] = useState<string>(merckHome);

    const reagentTypeList: ITDictValue[] = useMemo(() => {
      return getDictValuesByKey("reagentFormType");
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    const closeModal = () => {
      form.resetFields();
      setNistUrl("");
      setChemUrl("");
      changeEditingReagentData(null);
      changeShowAddEditModal(false);
    };

    const formFinish = async (values: ITReagent) => {
      let res = null;
      let msg: string = "";
      values.volatile = !!values.volatile;
      values.viscose = !!values.viscose;
      if (imgUrl) {
        if (
          imgUrl.substr(0, 7).toLowerCase() === "http://" ||
          imgUrl.substr(0, 8).toLowerCase() === "https://"
        ) {
          values.structural = imgUrl;
        } else {
          values.structural = `/project/images/${imgUrl}`;
        }
      } else {
        values.structural = "";
      }

      const userInfo = getUserInfo();
      values.user = userInfo.id;
      if (!values.id) {
        // 新增
        res = await addUserReagent(values);
        msg = lang["langaddsuccess"];
      } else {
        // 编辑
        res = await editUserReagent(values);
        msg = lang["langmodifysuccess"];
      }
      if (!res) {
        closeModal();

        if (searchList && searchList.length > 0) {
          let modifyIndex = -1;
          searchList.some((item: any, index: number) => {
            if (item.id === values.id) {
              modifyIndex = index;
              return true;
            }
            return false;
          });

          searchList[modifyIndex] = { ...values };
          changeSearchList([...searchList]);
        } else {
            getAllReagetList()
            getUserReagentList({
                user: userInfo?.id,
            });
        }
        message.success(msg);
      } else {
        const { msg } = res;
        message.error(msg);
      }
    };

    const props: UploadProps = {
      listType: "picture-card",
      action: "/api/reagent/structural",
      headers: {
        token: sessionStorage.getItem("TOKEN") || "",
      },
      showUploadList: { showPreviewIcon: false },
      beforeUpload(file: RcFile) {
        const isJpgOrPng =
          file.type === "image/jpeg" || file.type === "image/png";
        if (!isJpgOrPng) {
          message.error("You can only upload JPG/PNG file!");
          return false;
        }
        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isLt2M) {
          message.error("Image must smaller than 2MB!");
          return false;
        }
        return isJpgOrPng && isLt2M;
      },
      onChange(info) {
        if (info.file.status !== "uploading") {
        }
        if (info.file.status === "done") {
          message.success(`${info.file.name} file uploaded successfully`);
          const { response } = info.file;
          if (response.success) {
            setImgUrl(response.data.fileName);
          }
        } else if (info.file.status === "error") {
          message.error(`${info.file.name} file upload failed.`);
        }
      },
      onRemove() {
        setImgUrl("");
      },
    };

    const normFile = (e: any) => {
      if (Array.isArray(e)) {
        return e;
      }
      return e?.fileList;
    };

    const getReagentInfo = async () => {
      const tempCasno = form.getFieldValue("casno");
      if (tempCasno) {
        setGetStructLoading(true);
        const result: any = await getReagentInfoByCasno({ casno: tempCasno });
        setGetStructLoading(false);
        if (!result) {
          message.warning(lang["langnotfound"]);
          return false;
        }

        const {
          cnname,
          enname,
          formula,
          density,
          mw,
          structural,
          bp,
          mp,
          type,
          volatile,
          viscose,
          abbreviation,
          percentage,
        } = result;
        const cnnameArr = cnname.split(";");

        let structureName = "";

        try {
          if (structural && structural.indexOf("http") >= 0) {
            const urlarr = structural.split("/");
            if (urlarr && urlarr.length) {
              structureName = urlarr[urlarr.length - 1];
            }
          }
        } catch (e) {}

        let tempDensity: string | number = "";
        if (density) {
          tempDensity = parseFloat(density);
        }

        const formDataObj = {
          cnname: cnnameArr[0],
          name: enname,
          formula,
          type,
          density: tempDensity,
          mw,
          bp,
          mp,
          volatile,
          viscose,
          abbreviation,
          percentage,
          reagentstructure: [
            {
              uid: "-1",
              name: structureName,
              status: "done",
              url: structural,
            },
          ],
          // structural,
        };

        form.setFieldsValue(formDataObj);
        setImgUrl(structural);
      }
    };

    useEffect(() => {
      if (editingReagentData) {
        form.setFieldsValue(editingReagentData);
        const { structural, casno } = editingReagentData;
        let structureName = "";
        if (structural && structural.indexOf("http") >= 0) {
          const urlarr = structural.split("/");
          if (urlarr && urlarr.length) {
            structureName = urlarr[urlarr.length - 1];
          }
        }
        form.setFieldsValue({
          reagentstructure: [
            {
              uid: "-1",
              name: structureName,
              status: "done",
              url: structural,
            },
          ],
        });
        setImgUrl(structural);

        let tempNistUrl = "";
        let tempChemUrl = "";
        if (!!casno) {
          tempNistUrl = `${nistSearchCas}${casno}`;
          // tempChemUrl = `${chemsrc}${casno}/`;
          tempChemUrl = mercksrc(casno);
        } else {
          tempNistUrl = nistSearchUrl;
          tempChemUrl = merckHome;
        }
        setNistUrl(tempNistUrl);
        setChemUrl(tempChemUrl);
      }
    }, [editingReagentData, form]);

    const casnoChange = (
      e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
    ) => {
      const casno = e.target.value;
      let tempNistUrl = "";
      let tempChemUrl = "";
      if (!!casno) {
        tempNistUrl = `${nistSearchCas}${casno}`;
        // tempChemUrl = `${chemsrc}${casno}/`;
        tempChemUrl = mercksrc(casno);
      } else {
        tempNistUrl = nistSearchUrl;
        tempChemUrl = merckHome;
      }
      setNistUrl(tempNistUrl);
      setChemUrl(tempChemUrl);
    };

    return (
      <Modal
        title={
          !!editingReagentData
            ? lang["langeditreagent"]
            : lang["langaddreagent"]
        }
        open={showAddEditModal}
        destroyOnClose={true}
        onOk={() => {
          form.submit();
        }}
        onCancel={closeModal}
        confirmLoading={addEditReagentLoading}
        width={960}
      >
        <Form {...layout} form={form} name="dictForm" onFinish={formFinish}>
          <Form.Item name="id" label="" hidden={true}>
            <Input />
          </Form.Item>
          <Row gutter={24}>
            <Col span={12}>
              <Form.Item
                name="name"
                label={lang["langname"]}
                rules={[{ required: true }]}
              >
                <Input />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item name="abbreviation" label={lang["langabbreviation"]}>
                <Input />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item name="cnname" label={lang["langcnname"]}>
                <Input />
              </Form.Item>
            </Col>
            <Col span={12}>
              {/* 分子式 */}
              <Form.Item name="formula" label={lang["langformula"]}>
                <Input />
              </Form.Item>
            </Col>
            <Col span={12}>
              {/* 分子量 */}
              <Form.Item name="mw" label={lang["langmolecularweight"]}>
                <InputNumber style={{ width: "100%" }} />
              </Form.Item>
            </Col>
            <Col span={12}>
              {/* 密度 */}
              <Form.Item name="density" label={lang["langdensity"]}>
                <InputNumber style={{ width: "100%" }} />
              </Form.Item>
            </Col>
            <Col span={12}>
              {/* 百分含量 */}
              <Form.Item name="percentage" label={lang["langpercentage"]}>
                <InputNumber style={{ width: "100%" }} />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item
                name="type"
                label={lang["langtype"]}
                rules={[{ required: true }]}
              >
                <Select>
                  {reagentTypeList.map(({ cnlabel, label, value, sort }) => (
                    <Option key={sort} value={value}>
                      {langCur === "en" ? label : cnlabel}
                    </Option>
                  ))}
                </Select>
              </Form.Item>
            </Col>
            <Col span={12}>
              {/* 熔点 */}
              <Form.Item name="mp" label={lang["langmeltingpoint"]}>
                <Input />
              </Form.Item>
            </Col>
            <Col span={12}>
              {/* 沸点 */}
              <Form.Item name="bp" label={lang["langboilingpoint"]}>
                <Input />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item
                name="casno"
                label={lang["langcasno"]}
                // labelCol={{ span: 4 }}
                // wrapperCol={{ span: 20 }}
                extra={
                  <span>
                    {lang["reagentsearch"]}{" "}
                    <a href={nistUrl} target="_blank" rel="noreferrer">
                      NIST
                    </a>{" "}
                    <a
                      href={chemUrl}
                      target="_blank"
                      rel="noreferrer"
                      style={{ color: "#432c78", fontWeight: "bold" }}
                    >
                      MERCK
                    </a>
                  </span>
                }
              >
                <Input onChange={casnoChange} />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Space>
                <Button
                  type="primary"
                  onClick={getReagentInfo}
                  loading={getStructLoading}
                  icon={<CloudDownloadOutlined />}
                >
                  {lang["langgetinfobycas"]}
                </Button>

                <Tooltip title={lang["langgetcasnotip"]}>
                  <InfoCircleOutlined />
                </Tooltip>
              </Space>
            </Col>
            <Col span={12}>
              <Form.Item
                name="volatile"
                label={lang["langvolatile"]}
                valuePropName="checked"
              >
                <Switch
                  checkedChildren={lang["langyes"]}
                  unCheckedChildren={lang["langno"]}
                />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item
                name="viscose"
                label={lang["langviscose"]}
                valuePropName="checked"
              >
                <Switch
                  checkedChildren={lang["langyes"]}
                  unCheckedChildren={lang["langno"]}
                />
              </Form.Item>
            </Col>
            <Col span={24}>
              {/* 结构式 */}
              <Form.Item
                name="reagentstructure"
                label={lang["langstructuralformula"]}
                labelCol={{ span: 4 }}
                wrapperCol={{ span: 20 }}
                valuePropName="fileList"
                getValueFromEvent={normFile}
              >
                <Upload {...props} name="structuralup">
                  {!imgUrl && (
                    <div>
                      <PlusOutlined />
                      <div style={{ marginTop: 8 }}>Upload</div>
                    </div>
                  )}
                </Upload>
              </Form.Item>
            </Col>
            <Col span={24}>
              <Form.Item
                name="note"
                labelCol={{ span: 4 }}
                wrapperCol={{ span: 20 }}
                label={lang["langnote"]}
              >
                <Input.TextArea />
              </Form.Item>
            </Col>
            {/* <Col span={12}></Col> */}
          </Row>
        </Form>
      </Modal>
    );
  })
);

const ScanCasModal: FC<ITScanModalProp | any> = inject("store")(
  observer(({ store, showScanCasModal, close }: ITScanModalProp) => {
    const {
      languageStore: { lang },
      reagentStore: {
        getReagentInfoByCasno,
        changeEditingReagentData,
        changeShowAddEditModal,
      },
    } = store;

    const videoRef = useRef<any>();

    const canvasRef = useRef<any>();

    const casFormRef = useRef<any>();

    const [cameraTrack, setCameraTrack] = useState<any>(null);

    const [showCanvas, setShowCanvas] = useState<boolean>(false);

    const [scanLoading, setScanLoading] = useState<boolean>(false);

    const [showRescan, setShowRescan] = useState<boolean>(false);

    const [searchLoading, setSearchLoading] = useState<boolean>(false);

    const readerImage = async (Img: any) => {
      setScanLoading(true);
      const worker = createWorker({
        logger: (m) => {
          //console.log(m)
        },
      });
      await worker.load();
      await worker.loadLanguage("eng");
      await worker.initialize("eng");
      await worker.setParameters({
        tessedit_char_whitelist: "0123456789-",
      });
      const {
        data: { text },
      } = await worker.recognize(Img);
      const casregx = /(\d{2,7})(-)(\d{2})(-)(\d{1})/;
      const textMatchResult = text.match(casregx);
      // console.log(text);
      // console.log("------------")
      if (textMatchResult) {
        casFormRef.current.setFieldsValue({
          casval: textMatchResult[0],
        });
      } else {
        message.warning(lang["langscanerr"]);
      }
      await worker.terminate();
      setScanLoading(false);
      setShowRescan(true);
    };

    const closeModal = () => {
      close();
    };

    const closeCamera = () => {
      if (cameraTrack) {
        let tracks = cameraTrack.getTracks();
        tracks.forEach((item: any) => {
          item.stop();
        });
        setCameraTrack(null);
      }
    };

    const openCamera = () => {
      const constraints = {
        video: {
          winth: 400,
          height: 300,
        },
        audio: false,
      };
      if (!navigator.mediaDevices) {
        message.error(lang["langcameraerr"]);
        return false;
      }
      navigator.mediaDevices
        .getUserMedia(constraints)
        .then((mediaStream) => {
          if (videoRef.current) {
            videoRef.current.srcObject = mediaStream;
            videoRef.current.play();
            setCameraTrack(mediaStream);
          }
        })
        .catch((e) => {
          message.error(lang["langcameraerr"]);
        });
    };

    const scanImg = () => {
      videoRef.current.pause();
      const ctx = canvasRef.current.getContext("2d");
      ctx.drawImage(videoRef.current, 0, 0, 400, 300);
      setShowCanvas(true);
      closeCamera();
      readerImage(canvasRef.current);
    };

    useEffect(() => {
      if (showScanCasModal) {
        openCamera();
      } else {
        closeCamera();
      }

      return () => {
        closeCamera();
      };
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [showScanCasModal]);

    const handleClickScan = () => {
      if (showRescan) {
        // const ctx = canvasRef.current.getContext("2d");
        // ctx.clear();
        casFormRef.current.resetFields();
        setShowCanvas(false);
        openCamera();
        setShowRescan(false);
      } else {
        scanImg();
      }
    };

    const onFinish = async (values: TCasForm) => {
      setSearchLoading(true);
      const result: any = await getReagentInfoByCasno(values);
      setSearchLoading(false);
      if (result) {
        const {
          cnname,
          enname,
          formula,
          desc,
          density,
          mw,
          structural,
          mp,
          bp,
          abbreviation,
          percentage,
        } = result;
        const cnnameArr = cnname.split(";");
        let type = "";
        try {
          if (desc.indexOf("粉末") >= 0) {
            type = "powder";
          } else if (desc.indexOf("液体") >= 0) {
            type = "pure_liquid";
          }
        } catch (e) {}

        let formDataObj = {
          cnname: cnnameArr[0],
          name: enname,
          formula,
          type,
          casno: values.casno,
          density,
          mw,
          structural,
          mp,
          bp,
          percentage,
          abbreviation,
        };

        closeModal();
        changeEditingReagentData(formDataObj);
        changeShowAddEditModal(true);

        // 弹弹出编辑框
      } else {
        message.error(lang["langnotfound"]);
      }
    };

    return (
      <Modal
        title={lang["langscancascode"]}
        open={showScanCasModal}
        onOk={() => {
          casFormRef.current.submit();
        }}
        onCancel={closeModal}
        confirmLoading={searchLoading}
        destroyOnClose={true}
        // width="50%"
      >
        {!showCanvas && (
          <Row>
            <Col span={24} style={{ height: 300 }}>
              <div style={{ display: "flex", justifyContent: "center" }}>
                <video ref={videoRef}></video>
              </div>
            </Col>
          </Row>
        )}
        <Row>
          <Col span={24}>
            <div style={{ display: "flex", justifyContent: "center" }}>
              <canvas
                ref={canvasRef}
                width="400"
                height="300"
                style={{ display: showCanvas ? "" : "none" }}
              ></canvas>
            </div>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <div
              style={{ display: "flex", justifyContent: "center", margin: 10 }}
            >
              <Button
                type="primary"
                size="large"
                onClick={handleClickScan}
                loading={scanLoading}
              >
                {showRescan ? lang["langrescan"] : lang["langscan"]}
              </Button>
            </div>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <div style={{ display: "flex", justifyContent: "center" }}>
              <Form
                name="casform"
                layout="inline"
                onFinish={onFinish}
                ref={casFormRef}
              >
                <Form.Item label="" name="casno" rules={[{ required: true }]}>
                  <Input style={{ textAlign: "center" }} size="large" />
                </Form.Item>
              </Form>
            </div>
          </Col>
        </Row>
      </Modal>
    );
  })
);

const ReagentUser: FC<TProp | any> = ({ store }: TProp): JSX.Element => {
  const [searchForm] = Form.useForm();
  const [showScanCasModal, setShowScanCasModal] = useState(false);

  const [showCasImportModal, setShowCasImportModal] = useState<boolean>(false);

  const changeShowCasModal = (isShow: boolean) => {
    setShowCasImportModal(isShow);
  };

  const closeScanModal = () => {
    setShowScanCasModal(false);
  };

  return (
    <>
      {/* 搜索和新增按钮组件 */}
      <SearchAddComp
        searchForm={searchForm}
        setShowScanCasModal={setShowScanCasModal}
        changeShowCasModal={changeShowCasModal}
      />

      {/* 试剂列表 */}
      <ReagentList />

      {/* 新增编辑试剂弹窗 */}
      <ReagentModal />

      {/* 导入数据弹窗 */}
      <ImportModal />

      {/* Cas号批量导入 */}
      <CasImportModal
        isShow={showCasImportModal}
        changeShow={changeShowCasModal}
      />

      {/* 导出数据弹窗 */}
      <ExportModal />

      {/* 扫描cas弹出 */}
      <ScanCasModal
        showScanCasModal={showScanCasModal}
        close={closeScanModal}
      />
    </>
  );
};
export default inject("store")(observer(ReagentUser));
